#ifndef _QUEUE_H
#define _QUEUE_H

#include <list>
#include <queue>

#pragma once

template <class T>
class CQueue : public queue<T>
{
private:
	CRITICAL_SECTION m_ListLock;
public:
	CQueue(void) 
	{
		::InitializeCriticalSection(&m_ListLock);
	}
	virtual ~CQueue(void) 
	{
		::DeleteCriticalSection(&m_ListLock);
	}

	unsigned long GetSize()
	{ 
		unsigned long count = 0;
		::EnterCriticalSection(&m_ListLock);
		count = (unsigned long)size(); 
		::LeaveCriticalSection(&m_ListLock);
		return count;
	}

	void Push(T lpData)
	{
		::EnterCriticalSection(&m_ListLock);
		push(lpData);
		::LeaveCriticalSection(&m_ListLock);
	}

	T Pop()
	{
		T lpData = NULL;
		::EnterCriticalSection(&m_ListLock);
		if(size())
		{
			lpData = front();
			pop(); 
		}
		::LeaveCriticalSection(&m_ListLock);
		return lpData;
	}

	bool Empty()
	{
		bool bRet = false;
		::EnterCriticalSection(&m_ListLock);
		bRet =  empty();
		::LeaveCriticalSection(&m_ListLock);
		return bRet;
	}
};

template <class T>
class Clist : public list<T>
{
private:
	CRITICAL_SECTION m_ListLock;
public:
	Clist(void) 
	{
		::InitializeCriticalSection(&m_ListLock);
	}
	virtual ~Clist(void) 
	{
		::DeleteCriticalSection(&m_ListLock);
	}

	unsigned long GetSize()
	{ 
		unsigned long count = 0;
		::EnterCriticalSection(&m_ListLock);
		count = (unsigned long)size(); 
		::LeaveCriticalSection(&m_ListLock);
		return count;
	}

	void Push(T lpData)
	{
		::EnterCriticalSection(&m_ListLock);
		push_back(lpData);
		::LeaveCriticalSection(&m_ListLock);
	}

	T Pop()
	{
		T lpData = NULL;
		::EnterCriticalSection(&m_ListLock);
		if(size())
		{
			lpData = front();
			pop_front(); 
		}
		::LeaveCriticalSection(&m_ListLock);
		return lpData;
	}
	bool Empty()
	{
		bool bRet = false;
		::EnterCriticalSection(&m_ListLock);
		bRet =  empty();
		::LeaveCriticalSection(&m_ListLock);
		return bRet;
	}
};

#endif